package com.csun.cmny.provider.controller.admin;

import com.csun.cmny.base.constant.WebSocketConstant;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.provider.model.domain.UacUser;
import com.csun.cmny.provider.model.dto.SendMessageRequest;
import com.csun.cmny.provider.model.dto.SendWebSocketRequest;
import com.csun.cmny.provider.model.enums.UacUserStatusEnum;
import com.csun.cmny.provider.model.exceptions.UacBizException;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.OpcMessageService;
import com.csun.cmny.provider.service.OpcWebSocketService;
import com.csun.cmny.provider.service.UacGroupLanguageService;
import com.csun.cmny.provider.service.UacUserService;
import com.csun.cmny.provider.utils.Md5Util;
import com.csun.cmny.util.wrapper.WrapMapper;
import com.csun.cmny.util.wrapper.Wrapper;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Decoder;
import sun.net.www.protocol.http.HttpURLConnection;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-10-11 10:27
 * @Description: the class uac api controller
 */
@Slf4j
@RestController
@RequestMapping(value = "/api")
@Api(value = "Web-AuthRestController", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class UacApiController {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private OpcWebSocketService opcWebSocketService;

    @Autowired
    private OpcMessageService opcMessageService;
    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private UacGroupLanguageService uacGroupLanguageService;
    @Resource
    private MessageSource messageSource;
    @Resource
    private UacUserService userService;

    /**
     * 代理第三方接口
     */
     @RequestMapping(value = "/requestOut", method = RequestMethod.POST)
    public Wrapper requestOut(@RequestParam Map<String, Object> params){
        log.info("/apo/requestPost : getMapData");
        String requestUrl = "";
        String requestMethod = "get";
        for (String mp : params.keySet()) {
            log.info("key = " + mp + ", value = " + params.get(mp));
            if (mp.equals("url")){
                requestUrl = (String) params.get(mp);
            }
            if (mp.equals("method")){
                requestMethod = (String) params.get(mp);
            }
        }
        if (params.containsKey("url")){
            params.remove("url");
        }
        if (params.containsKey("method")){
             params.remove("method");
        }
        String returnStr = "";
        if (requestMethod.equals("get")){
            returnStr = doGet(requestUrl);
        }else if (requestMethod.equals("postJson")){
            ObjectMapper json = new ObjectMapper();
            String params2= null;
            try {
                params2 = json.writeValueAsString(params);
                System.out.println("++++++++++++++++++转成的json格式字符串："+params2);
            } catch (JsonGenerationException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            returnStr = postForm(requestUrl,params2);
        }else if (requestMethod.equals("postForm")) {
            ObjectMapper json = new ObjectMapper();
            String params2= null;
            try {
                params2 = json.writeValueAsString(params);
                System.out.println("++++++++++++++++++转成的json格式字符串："+params2);
            } catch (JsonGenerationException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            returnStr = postJson(requestUrl,params2);
        }
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, "获取成功", returnStr);
    }


    /**
     * GET请求.
     *
     * @param url 请求地址
     * @return 响应数据
     */
    public static String doGet(String url) {
        HttpURLConnection urlConnection = null;
        try {
            // 新建URL对象
            URL urlObject = new URL(url);
            // 打开URL连接
            urlConnection = (HttpURLConnection) urlObject.openConnection();
            // 设置请求方法
            urlConnection.setRequestMethod("GET");
            // 设置请求头内容类型和字符集类型
            urlConnection.setRequestProperty("content-type", "application/json;charset=UTF-8");
            // 不使用缓存
            urlConnection.setUseCaches(false);
            // 设置连接超时时间，单位：毫秒
            urlConnection.setConnectTimeout(2000);
            // 设置读取数据超时时间，单位：毫秒
            urlConnection.setReadTimeout(2000);
            InputStream inputStream = urlConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String body = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator()));
            if (urlConnection.getResponseCode() == 200){
                return body;
            }else{
                return "{\"code\": \"-1\", \"msg\":\"接口异常\"}";
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public static String postForm(String sUrl, String jsonStrParam) {
        try {
            // Configure and open a connection to the site you will send the request
            URL url = new URL(sUrl);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            // 设置doOutput属性为true表示将使用此urlConnection写入数据
            urlConnection.setDoOutput(true);
            // 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
            urlConnection.setRequestProperty("content-type", "application/x-www-form-urlencoded");
            // 得到请求的输出流对象
            OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
            // 把数据写入请求的Body
            out.write(jsonStrParam);
            out.flush();
            out.close();
            // 从服务器读取响应
            InputStream inputStream = urlConnection.getInputStream();
//            String encoding = urlConnection.getContentEncoding();
            String body = new BufferedReader(new InputStreamReader(inputStream))
                    .lines().collect(Collectors.joining(System.lineSeparator()));
//            String body = IOUtils.toString(inputStream, encoding);
            if (urlConnection.getResponseCode() == 200) {
                return body;
            } else {
                String s = "{\"code\": \"-1\", \"msg\":\"接口异常\"}";
                return s;
            }
        } catch (IOException e) {
            String s = "{\"code\": \"-1\", \"msg\":\"接口异常\"}";
            return s;
        }
    }

    public static String postJson(String sUrl, String jsonStr) {
        try {
            // Configure and open a connection to the site you will send the request
            URL url = new URL(sUrl);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            // 设置doOutput属性为true表示将使用此urlConnection写入数据
            urlConnection.setDoOutput(true);
            // 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
            urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            // 得到请求的输出流对象
            OutputStream os = urlConnection.getOutputStream();
            os.write(jsonStr.getBytes(StandardCharsets.UTF_8));
//            OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
//            // 把数据写入请求的Body
//            out.write(jsonStr);
            os.flush();
            os.close();
            // 从服务器读取响应
            InputStream inputStream = urlConnection.getInputStream();
//            String encoding = urlConnection.getContentEncoding();
            String body = new BufferedReader(new InputStreamReader(inputStream))
                    .lines().collect(Collectors.joining(System.lineSeparator()));
//            String body = IOUtils.toString(inputStream, encoding);
            if (urlConnection.getResponseCode() == 200) {
                return body;
            } else {
                String s = "{\"code\": \"-1\", \"msg\":\"接口异常\"}";
                return s;
            }
        } catch (Exception e) {
            String s = "{\"code\": \"-1\", \"msg\":\"接口异常\"}";
            return s;
        }
    }

    /**
     * 推送消息
     */
    @PostMapping(value = "/sendMessageWithUserIdList")
    public Wrapper sendMessageWithUserIdList(@RequestBody SendWebSocketRequest sendWebSocketRequest) {

        sendWebSocketRequest.setMsgType(WebSocketConstant.WEBSOCKET_WITH_USER_ID_LIST);

        opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));
    }

    /**
     * 推送消息
     */
    @PostMapping(value = "/sendMessageWithGroupId")
    public Wrapper sendMessageWithGroupId(@RequestBody SendWebSocketRequest sendWebSocketRequest) {

        sendWebSocketRequest.setMsgType(WebSocketConstant.WEBSOCKET_WITH_GROUP_ID);

        opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));
    }

    /**
     * 推送消息
     */
    @PostMapping(value = "/sendMessageWithRoleCodeList")
    public Wrapper sendMessageWithRoleCodeList(@RequestBody SendWebSocketRequest sendWebSocketRequest) {

        sendWebSocketRequest.setMsgType(WebSocketConstant.WEBSOCKET_WITH_ROLE_CODE_LIST);

        opcWebSocketService.sendWebSocketMessage(sendWebSocketRequest);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));
    }

    @PostMapping(value = "/sendMessageWithUser")
    public Wrapper sendMessageWithUser(@RequestBody SendMessageRequest sendMessageRequest) {

        opcMessageService.pushByUser(sendMessageRequest);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));
    }

    @PostMapping(value = "/sendMessageWithCode")
    public Wrapper sendMessageWithCode(@RequestBody SendMessageRequest sendMessageRequest) {

        opcMessageService.pushWithMsgCode(sendMessageRequest);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));
    }

    @PostMapping(value = "/throwExec")
    public Wrapper throwExec(Integer result, Long groupId, String code) {

        switch (result) {
            case 0 :
                return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                        .getMessage("operation.success", null));
            case 1 :
                return WrapMapper.wrap(Wrapper.ERROR_CODE, cmnyMessageSource
                        .getMessage("operation.failed", null));
            case 2 :
                throw new UacBizException(ErrorCodeEnum.UAC10012009);
            case 3 :
                throw new UacBizException(ErrorCodeEnum.UAC10013001, 1);
            case 4 :
                // 获取消息模板
                /**
                 * 根据机构Id获取语言配置，默认中文
                 *
                 * 使用语言和配置模板获取消息模块
                 */

//                redisTemplate.opsForValue().set(RedisKeyUtil.getCsunGatewayKey(dmcDevice.getDeviceNo()),
//                    csunGatewayData);

//                String msgFormat = getMsgFormat(groupId, code);
//                String msgFormat = "[%s]的[%s]使用紧急按钮进行了呼叫, 请前往处理!";
//                String message = String.format(msgFormat, "param-1", "param-2");
                Object params[] = {"param-1", "param-2"};
//                String language = uacGroupLanguageService.getLanguageByGroupId(groupId);
//                String message = cmnyMessageSource.getMessage(code, param, language);
//                log.info("language = {}", language);
//                Locale locale = Objects.nonNull(language) ? new Locale(language) : Locale.getDefault();
//                String message = messageSource.getMessage(code, params, locale);

                String message = cmnyMessageSource.getMessage(code, params, groupId);

                return WrapMapper.wrap(Wrapper.SUCCESS_CODE, message);

        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));
    }

    @RequestMapping(value = "/image", produces = {"text/html; charset=UTF-8"})
    public void image(HttpServletRequest request, HttpServletResponse response) {

        try {

            String picture = "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SGf/2Q==U1weOKM0LTsUhiZNA4pTxSdaAHA0nAPFL0FMzmgB9FIDRSGf/9k=WpCGc7m6VlXVqUHmryO49Ks6bejIhkPX7p/pS8h2vqa4PHFLn86FpcUDEyaBSnik60APBpvAJpRwKbnJoAfRTQcUUhn/2Q==jbedDvX76/qKklkCnjrVdrhnO1atRJcuxWsL0wZjb7h6e1akO523N0rJurVkHmjkd6tabejIhkPX7p/pR5Ba+prA8cUufWkWnYpDEzSijpSdaAHg03ABOKUcU3OaBj6KQGikB//ZQA8GkwAeKBwKaTmgY+imqaKQz//Z";

            if (StringUtils.isEmpty(picture)) {
                System.out.println("picture is null");
            } else {
                ByteArrayInputStream byteArrayInputStream = null;
                try {
                    BASE64Decoder decoder = new BASE64Decoder();
                    byte[] byteArray = decoder.decodeBuffer(picture);
                    byteArrayInputStream = new ByteArrayInputStream(byteArray);
                    //BufferedImage bufferedImage = ImageIO.read(byteArrayInputStream);

                    org.springframework.core.io.Resource resource = new ClassPathResource("static/default.png");
                    InputStream is = resource.getInputStream();
                    BufferedImage bufferedImage = ImageIO.read(is);
//                    if (bufferedImage == null) {
//                        log.error("====> 拍照失败...");
//                        return false;
//                    }

//                    File outputfile  = new File("G:/lu-1.jpg");
//                    ImageIO.write(bufferedImage,"jpg",outputfile);
//
//                    String image = imageToBase64("G:/lu-1.jpg");
//
//
//                    log.info("picture = {}", picture);
//                    log.info("image = {}", image);
                    ImageIO.write(bufferedImage, "png", response.getOutputStream());
                    //response.setContentType("image/png");
                    response.setContentType("application/octet-stream");
                    response.flushBuffer();
                } finally {
                    if (byteArrayInputStream != null) {
                        byteArrayInputStream.close();
                    }
                }
            }

//            File file=File.createTempFile("qrcode"+System.currentTimeMillis(), ".png");
//            ImageIO.write(bufferedImage, "png", file);


//            ImageIO.write(bufferedImage, "png", response.getOutputStream());
//
//            response.setContentType("image/png");
//            response.flushBuffer();

        } catch (Exception e) {
            e.printStackTrace();
//            LOG.error("transform image stream error",e);
        }

    }

    /**
     * 邮箱激活账号链接
     */
    @GetMapping(value = "/activationEmail")
    public Wrapper activationEmail(Long userId) {

        UacUser user = new UacUser();
        user.setId(userId);
        user.setStatus(UacUserStatusEnum.ENABLE.getKey());

        int update = userService.update(user);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("email.activate.ok", null));
    }

    /**
     * 日本居家app重置密码
     */
    @GetMapping(value = "/resetPassword")
    public Wrapper resetPassword(Long userId) {

        UacUser user = new UacUser();
        user.setId(userId);
        user.setLoginPwd(Md5Util.encrypt("123456")
        );

        int update = userService.update(user);

        //return WrapMapper.ok();
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("email.this.reset.ok", null));
    }

    /**
     * 设置应用开关状态
     *
     * @param application   应用名
     * @param status        状态 0-关 1-开
     *
     * @return  the wrapper.
     */
    @PostMapping(value = "/setSwitch")
    public Wrapper setSwitch(String application, Integer status) {

        redisTemplate.opsForValue().set(application, status);

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null));

    }

    /**
     * 获取应用开关状态
     *
     * @param application   应用名
     *
     * @return  the wrapper.
     */
    @PostMapping(value = "/getSwitch")
    public Wrapper getSwitch(String application) {

        String value = redisTemplate.opsForValue().get(application) + "";

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, cmnyMessageSource
                .getMessage("operation.success", null), value);
    }
}
